<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>抽象工厂模式</title>
    <script>
        function FormFieldFactory() {
            this.availableTypes = {
                TEXT: "text",
                EMAIL: "email",
                BUTTON: 'button'
            }
        }
        FormFieldFactory.prototype = {
            makeField: () => {
                throw new Error("This is should not be called directly.")
            }
        }

        function Html5FormFieldFactory() {

        }
        Html5FormFieldFactory.prototype = new FormFieldFactory();
        Html5FormFieldFactory.prototype.makeField =function (options) {
            var options = options || {},
                type = options.type || this.availableTypes.TEXT,
                displayText = options.displayText || '',
                field;
            switch (type) {
                case this.availableTypes.TEXT:
                    field = new Html5TextField(displayText)
                    break;
                case this.availableTypes.EMAIL:
                    field = new Html5EmailField(displayText)
                    break;
                case this.availableTypes.BUTTON:
                    field = new ButtonField(displayText)
                    break;
                default:
                    throw new Error('Invaild field type specified:' + type)
                    break;
            }
            return field;
        }

        function Html4FormFieldFactory() {}
        Html4FormFieldFactory.prototype = new FormFieldFactory();
        Html4FormFieldFactory.prototype.makeField = function (options) {
            var options = options || {},
                type = options.type || this.availableTypes.TEXT,
                displayText = options.displayText || '',
                field;
            switch (type) {
                case this.availableTypes.TEXT:
                case this.availableTypes.EMAIL:
                    field = new Html4TextField(displayText)
                    break;
                case this.availableTypes.BUTTON:
                    field = new ButtonField(displayText)
                    break;
                default:
                    throw new Error('Invaild field type specified:' + type)
                    break;
            }
            return field;
        }

        function Html5TextField(displayText) {
            this.displayText = displayText
        }
        Html5TextField.prototype.getElement = function () {
            let textField = document.createElement("input")
            textField.setAttribute("type", 'text')
            textField.setAttribute("placeholder", this.displayText)
            return textField;
        }

        function Html4TextField(displayText) {
            this.displayText = displayText
        }
        Html4TextField.prototype.getElement = function () {
            let wrapper = document.createElement("div"),
                textField = document.createElement("input"),
                textFieldId = "text-field-" + Math.floor(Math.random() * 999),
                label = document.createElement("label"),
                labelText = document.createTextNode(this.displayText);

            textField.setAttribute("type", 'text')
            textField.setAttribute("id", textFieldId);
            label.setAttribute("for", textFieldid);
            label.appendChild(labelText);

            wrapper.appendChild(textField);
            wrapper.appendChild(label)
            return wrapper;
        }

        function Html5EmailField(displayText) {
            this.displayText = displayText
        }
        Html5EmailField.prototype.getElement = function () {
            let emailField = document.createElement("input")
            emailField.setAttribute("type", 'email')
            emailField.setAttribute("placeholder", this.displayText)
            return emailField;
        }

        function ButtonField(displayText) {
            this.displayText = displayText
        }
        ButtonField.prototype.getElement = function () {
            let button = document.createElement("input")
            button.setAttribute("type", 'submit')
            button.innerHTML = this.displayText;
            return button;
        }
        var supportHtmlFormFields = (function () {
                var field = document.createElement('input');
                field.setAttribute("type", "email")
                return field.type === 'email'
            })(),
            FormFieldFactory = supportHtmlFormFields ? new Html5FormFieldFactory() : new Html4FormFieldFactory();
            console.log(FormFieldFactory);
        var textField = FormFieldFactory.makeField({
                type: "text",
                displayText: 'Enter the first line of your address'
            }),
            emailField = FormFieldFactory.makeField({
                type: "email",
                displayText: 'Enter  your email'
            }),
            buttonField = FormFieldFactory.makeField({
                type: "button",
                displayText: 'Submit'
            });
        window.addEventListener("load", () => {
            let bodyElement = document.body;
            bodyElement.appendChild(textField.getElement())
            bodyElement.appendChild(emailField.getElement())
            bodyElement.appendChild(buttonField.getElement())
        }, false)
    </script>
</head>

<body>

</body>

</html>